
import btree4j.BTreeException;
import btree4j.Value;
import btree4j.template.*;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class DataSecondaryIndexData {

    public static void main(String[] args) {
        // 1. 初始化测试环境
        File dataDir = new File("test_data");
//        if (dataDir.exists()) {
//            deleteDir(dataDir); // 清理旧测试数据
//        }
//        dataDir.mkdirs();

        try {
            TemplateManager templateManager = new TemplateManager(dataDir);
            TemplateDataOperator dataOperator = new TemplateDataOperator(templateManager);

            // 2. 创建带二级索引的模板
            Template userTemplate = new Template("User");
            Column idCol = new Column("id", "INT", true, false); // 主键列
            Column emailCol = new Column("email", "STRING", false, true,true);
            Column nameCol = new Column("name", "STRING", false, true,true);
            emailCol.setIndexed(true); // 标记为二级索引列
            userTemplate.addColumn(idCol);
            userTemplate.addColumn(emailCol);
            userTemplate.addColumn(nameCol);
            //userTemplate.addIndexedColumn("email"); // 添加索引列
            //userTemplate.addIndexedColumn("name"); // 添加索引列
            long templateId = templateManager.createTemplate(userTemplate);
            System.out.println("模板创建成功，ID: " + templateId);

            // 3. 插入测试数据
            TemplateDataRow row1 = new TemplateDataRow(userTemplate);
            row1.setColumnValue("id", 1001);
            row1.setColumnValue("email", "alice@example.com");
            row1.setColumnValue("name", "alice");
            dataOperator.addData(templateId, row1);

            TemplateDataRow row2 = new TemplateDataRow(userTemplate);
            row2.setColumnValue("id", 1002);
            row2.setColumnValue("email", "bob@example.com");
            row2.setColumnValue("name", "bob");
            dataOperator.addData(templateId, row2);

            TemplateDataRow row3 = new TemplateDataRow(userTemplate);
            row3.setColumnValue("id", 1003);
            row3.setColumnValue("email", "cindy@example.com");
            row3.setColumnValue("name", "cindy");
            dataOperator.addData(templateId, row3);
            System.out.println("数据插入成功");

            // 4. 通过主键查询验证
            System.out.println("\n=== 主键查询测试 ===");
            TemplateDataRow result1 = dataOperator.getData(templateId, 1001);
            System.out.println("主键1001查询结果: " + result1);
            assert result1 != null : "主键查询失败";

            // 5. 二级索引查询测试
            System.out.println("\n=== 二级索引查询测试 ===");
            List<Value> emailResults = templateManager.queryBySecondaryIndex(templateId, "email", new Value("bob@example.com"));
            System.out.println("邮箱bob@example.com查询结果: " + emailResults);
            assert !emailResults.isEmpty() : "二级索引查询失败";
            Value pkValue = emailResults.get(0);
            System.out.println(pkValue);
            TemplateDataRow result2 = dataOperator.getData(templateId, pkValue);
            System.out.println("关联数据: " + result2);

            List<Value> nameResults = templateManager.queryBySecondaryIndex(templateId, "name", new Value("cindy"));
            System.out.println("姓名cindy查询结果: " + nameResults);
            assert !nameResults.isEmpty() : "二级索引查询失败";
            Value pkValuename = nameResults.get(0);
            System.out.println(pkValuename);
            TemplateDataRow result3 = dataOperator.getData(templateId, pkValuename);
            System.out.println("关联数据: " + result3);

            // 6. 更新数据并验证索引
            System.out.println("\n=== 更新数据测试 ===");
            TemplateDataRow updatedRow = new TemplateDataRow(userTemplate);
            updatedRow.setColumnValue("id", 1001);
            updatedRow.setColumnValue("email", "alice.new@example.com"); // 修改索引列
            updatedRow.setColumnValue("name", "alice");
            dataOperator.updateData(templateId, updatedRow);

            // 验证旧索引删除
            List<Value> oldEmailResults = templateManager.queryBySecondaryIndex(templateId, "email", new Value("alice@example.com"));
            System.out.println("旧邮箱查询结果（应空）: " + oldEmailResults);
            assert oldEmailResults.isEmpty() : "旧索引未删除";

            // 验证新索引添加
            List<Value> newEmailResults = templateManager.queryBySecondaryIndex(templateId, "email", new Value("alice.new@example.com"));
            System.out.println("新邮箱查询结果: " + newEmailResults);
            assert !newEmailResults.isEmpty() : "新索引未添加";
            Value pkValuenew = newEmailResults.get(0);
            System.out.println(pkValuenew);
            TemplateDataRow resultnew = dataOperator.getData(templateId, pkValuenew);
            System.out.println("关联数据: " + resultnew);

            // 7. 通过主键删除数据
            System.out.println("\n=== 主键删除测试 ===");
            dataOperator.removeData(templateId, 1001);
            TemplateDataRow deletedData = dataOperator.getData(templateId, 1001);
            System.out.println("删除后查询结果（应空）: " + deletedData);
            assert deletedData == null : "主键删除失败";

            // 8. 通过二级索引删除数据
            System.out.println("\n=== 二级索引email删除测试 ===");
            List<Value> deleteTargets = templateManager.queryBySecondaryIndex(templateId, "email", new Value("bob@example.com"));
            System.out.println(deleteTargets);
            for (Value pk : deleteTargets) {
                dataOperator.removeData(templateId, pk);
            }

            TemplateDataRow deletedData2 = dataOperator.getData(templateId, 1002);
            System.out.println("删除后查询结果（应空）: " + deletedData2);
            assert deletedData2 == null : "二级索引email删除失败";

            System.out.println("\n=== 二级索引name删除测试 ===");
            List<Value> deleteTargetsname = templateManager.queryBySecondaryIndex(templateId, "name", new Value("cindy"));
            System.out.println(deleteTargetsname);
            for (Value pk : deleteTargetsname) {
                dataOperator.removeData(templateId, pk);
            }

            TemplateDataRow deletedData3 = dataOperator.getData(templateId, 1003);
            System.out.println("删除后查询结果（应空）: " + deletedData3);
            assert deletedData2 == null : "二级索引name删除失败";


            System.out.println("\n=== 所有测试通过 ===");

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("测试失败: " + e.getMessage());
        }
    }

//    // 递归删除测试目录
//    private static void deleteDir(File dir) {
//        File[] files = dir.listFiles();
//        if (files != null) {
//            for (File f : files) {
//                if (f.isDirectory()) {
//                    deleteDir(f);
//                } else {
//                    f.delete();
//                }
//            }
//        }
//        dir.delete();
//    }
}